import os
import shutil
import ctypes
import sys
from pathlib import Path

def is_admin():
    """检查是否以管理员权限运行"""
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

def get_folder_info(folder_path):
    """获取文件夹信息：文件数量和总大小"""
    total_files = 0
    total_size = 0
    
    try:
        for root, dirs, files in os.walk(folder_path):
            for file in files:
                file_path = os.path.join(root, file)
                try:
                    size = os.path.getsize(file_path)
                    total_size += size
                    total_files += 1
                except (OSError, IOError):
                    # 忽略无法访问的文件
                    pass
    except Exception:
        pass
    
    return total_files, total_size

def format_size(size_bytes):
    """格式化文件大小显示"""
    if size_bytes == 0:
        return "0B"
    
    size_names = ["B", "KB", "MB", "GB", "TB"]
    i = 0
    while size_bytes >= 1024 and i < len(size_names) - 1:
        size_bytes /= 1024.0
        i += 1
    
    return f"{size_bytes:.1f}{size_names[i]}"

def copy_with_progress(source, target):
    """带进度显示的复制函数"""
    print(f"正在统计文件信息...")
    total_files, total_size = get_folder_info(source)
    
    if total_files == 0:
        print("源文件夹为空")
        return
    
    print(f"共 {total_files} 个文件，总大小 {format_size(total_size)}")
    print(f"开始复制...")
    
    copied_files = 0
    copied_size = 0
    
    def copy_function(src, dst, *, follow_symlinks=True):
        nonlocal copied_files, copied_size
        
        # 复制单个文件
        shutil.copy2(src, dst, follow_symlinks=follow_symlinks)
        
        try:
            file_size = os.path.getsize(src)
            copied_size += file_size
        except (OSError, IOError):
            pass
        
        copied_files += 1
        
        # 显示进度
        progress = (copied_files / total_files) * 100
        size_progress = format_size(copied_size)
        total_size_str = format_size(total_size)
        
        print(f"\r进度: {progress:.1f}% ({copied_files}/{total_files} 文件, {size_progress}/{total_size_str})", end='', flush=True)
    
    try:
        shutil.copytree(source, target, copy_function=copy_function, dirs_exist_ok=True)
        print(f"\n复制完成！")
    except Exception as e:
        print(f"\n复制过程中出错: {str(e)}")
        raise

def delete_with_progress(folder_path):
    """带进度显示的删除函数"""
    print(f"正在统计要删除的文件...")
    total_files, total_size = get_folder_info(folder_path)
    
    if total_files == 0:
        print("文件夹为空，直接删除")
        shutil.rmtree(folder_path)
        return
    
    print(f"共 {total_files} 个文件，总大小 {format_size(total_size)}")
    print(f"开始删除...")
    
    deleted_files = 0
    deleted_size = 0
    
    # 收集所有文件路径
    all_files = []
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            file_path = os.path.join(root, file)
            all_files.append(file_path)
    
    # 逐个删除文件并显示进度
    for file_path in all_files:
        try:
            file_size = os.path.getsize(file_path)
            os.remove(file_path)
            deleted_size += file_size
            deleted_files += 1
            
            # 显示进度
            progress = (deleted_files / total_files) * 100
            size_progress = format_size(deleted_size)
            total_size_str = format_size(total_size)
            
            print(f"\r进度: {progress:.1f}% ({deleted_files}/{total_files} 文件, {size_progress}/{total_size_str})", end='', flush=True)
            
        except (OSError, IOError):
            # 文件可能已被删除或无法访问，继续
            deleted_files += 1
    
    # 删除空目录
    print(f"\n正在删除空目录...")
    try:
        shutil.rmtree(folder_path)
        print("删除完成！")
    except Exception as e:
        print(f"删除目录时出错: {str(e)}")
        raise

def create_symlink():
    """执行单次符号链接创建操作"""
    # 获取用户输入
    source = input("请输入源文件夹路径（例如 \"C:\\Users\\Lenovo\\Downloads\"）: ").strip()
    target_parent = input("请输入目标父目录（例如 D:\\zhuomian）: ").strip()

    # 移除可能的引号
    source = source.strip('"').strip("'")
    target_parent = target_parent.strip('"').strip("'")

    # 提取源文件夹名称
    folder_name = os.path.basename(source)
    target = os.path.join(target_parent, folder_name)

    # 显示操作信息
    print(f"\n源文件夹: {source}")
    print(f"目标位置: {target}\n")

    # 检查源文件夹是否存在
    if not os.path.exists(source):
        print(f"错误: 源文件夹 '{source}' 不存在")
        return False

    # 处理已存在的目标文件夹
    if os.path.exists(target):
        confirm = input(f"目标文件夹 '{target}' 已存在，是否删除并重新创建？(y/n): ").strip().lower()
        if confirm != 'y':
            print("操作已取消")
            return False
        
        # 删除现有目标文件夹 - 带重试逻辑
        while True:
            try:
                print(f"删除现有目标文件夹 '{target}'...")
                if os.path.isdir(target):
                    delete_with_progress(target)
                else:
                    os.remove(target)
                    print("现有目标文件夹已删除")
                break  # 成功则跳出循环
            except Exception as e:
                print(f"错误: 无法删除现有目标文件夹 - {str(e)}")
                print("请手动删除后重试")
                input("按任意键重试...")
                # 继续循环重试

    # 复制文件 - 带重试逻辑和进度显示
    while True:
        try:
            copy_with_progress(source, target)
            break  # 成功则跳出循环
        except Exception as e:
            print(f"错误: 文件复制失败 - {str(e)}")
            input("按任意键重试...")
            # 继续循环重试

    # 删除原文件夹 - 带重试逻辑和进度显示
    while True:
        try:
            delete_with_progress(source)
            break  # 成功则跳出循环
        except Exception as e:
            print(f"错误: 无法删除原文件夹 - {str(e)}")
            print("请关闭所有使用该文件夹的程序后重试")
            input("按任意键重试...")
            # 继续循环重试

    # 创建符号链接
    try:
        print(f"正在创建符号链接...")
        os.symlink(target, source, target_is_directory=True)
        print("符号链接创建成功")
    except Exception as e:
        print(f"错误: 无法创建符号链接 - {str(e)}")
        return False

    # 完成
    print("\n所有操作完成！")
    print(f"'{source}' 已成功链接到 '{target}'")
    return True

def main():
    # 检查管理员权限
    if not is_admin():
        # 重新以管理员身份运行
        ctypes.windll.shell32.ShellExecuteW(
            None, "runas", sys.executable, " ".join(sys.argv), None, 1
        )
        return

    print("=== 符号链接创建工具 ===")
    print("此工具可以将文件夹移动到其他位置并创建符号链接\n")

    while True:
        # 执行一次符号链接创建
        success = create_symlink()
        
        # 询问是否继续
        print("\n" + "="*50)
        continue_choice = input("是否继续创建其他符号链接？(y/n): ").strip().lower()
        
        if continue_choice != 'y':
            print("程序结束，感谢使用！")
            input("按任意键退出...")
            break
        else:
            print("\n" + "="*50)
            print("开始下一个符号链接创建...\n")

if __name__ == "__main__":
    main()